package com.rainng.coursesystem.controller.admin;

import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.rainng.coursesystem.base.api.dto.PagingReqDTO;
import com.rainng.coursesystem.controller.BaseController;
import com.rainng.coursesystem.model.bo.LoginStatusBO;
import com.rainng.coursesystem.model.vo.response.ResultVO;
import com.rainng.coursesystem.module.plan.dto.baseEntity.testReportDataBaseEntity;
import com.rainng.coursesystem.module.plan.dto.entity.*;
import com.rainng.coursesystem.module.plan.dto.request.*;
import com.rainng.coursesystem.module.plan.dto.response.testReportDataRes;
import com.rainng.coursesystem.module.plan.service.SaveInsectionService;
import com.rainng.coursesystem.service.PlanService;
import com.rainng.coursesystem.model.taskplan.PlanStateUpdateVo;

import com.rainng.coursesystem.module.task.dto.request.TaskQueryReqDTO;
import com.rainng.coursesystem.module.task.dto.response.TaskPagingResDTO;
import com.rainng.coursesystem.service.UserService;
import com.rainng.coursesystem.util.FtpUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTPClient;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.json.simple.parser.ParseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.beans.Transient;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.math.BigInteger;
import java.net.URL;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;
import org.json.simple.parser.JSONParser;
/**
 *  将实验计划下发到逐渐任务接口
 */
@Slf4j
@Api(tags = "将实现计划下发成主检任务接口")
@RequestMapping("/v2/plan")
@RestController
public class PlanToInsepectionController extends BaseController {

    @Autowired
    private SaveInsectionService service;

    @Autowired
    private UserService user;

    @Autowired
    private PlanService planService;

    @Value("${template.recordDocxPath}")
    private String recordDocxPath;

    @Autowired
    private FtpUtil ftpUtil;

    @PostMapping("/insection")
    @ApiOperation(value = "主检任务指派")
    public ResultVO insection(@RequestBody PlanToInsepection reqDTO) {
        PlanStateUpdateVo vo = new PlanStateUpdateVo();
        vo.setPlanState(1);
        vo.setId(reqDTO.getPlanId());
        service.save(reqDTO);
        planService.updatePlanState(vo);
        return super.result();
    }
    @PostMapping("/updateStatus")
    @ApiOperation(value = "主检任务指派")
    public ResultVO updateStatus(@RequestBody PlanStatusDto reqDTO){
        service.updateStatus(reqDTO);
        if (reqDTO.getIsComplete().equals(1)) {
            PlanStateUpdateVo vo = new PlanStateUpdateVo();
            vo.setPlanState(2);
            vo.setId(reqDTO.getPlanId());
            planService.updatePlanState(vo);
        }
        return super.result();
    }

    /**
     * 上传文件
     */
    @PostMapping("/upload")
    public ResultVO upload(@RequestParam MultipartFile[] files, @RequestParam Integer assignId, @RequestParam String tire, @RequestParam String vin, @RequestParam String prjNum, @RequestParam String itemId, @RequestParam String userId) throws Exception {
        ResultVO res= user.getLoginStatus();
//        @RequestBody photoResultEntity photo,
        FTPClient connectionFTP = ftpUtil.getConnectionFTP();
        //文件的名称列表
        String filesName="";
        if (files.length==0) {
            throw new Exception("上传文件不能为空");
        }
        for(MultipartFile file: files){
            if (file.isEmpty()) {
                continue; // next pls
            }
            InputStream inputStream = file.getInputStream();
            String fileExt = file.getOriginalFilename();
            String filename= ftpUtil.uploadFile(connectionFTP,fileExt,inputStream);
            if(filesName==""){
                filesName=filename;
            }
            else {
                filesName=filesName+","+filename;
            }
            //关闭输入流
            inputStream.close();
        }
        //退出ftp
        connectionFTP.logout();
        //将照片上传数据录入数据库
        photoResultEntity photo=new photoResultEntity();
//        photo.setTaskCode(taskCode);
        photo.setVin(vin);
        photo.setFilesName(filesName);
        photo.setItemId(itemId);
        photo.setPrjNum(prjNum);
        photo.setTire(tire);
        photo.setAssignId(assignId);
        photo.setUserId(userId);
//        if(res.getCode()==0){
//            LoginStatusBO user=(LoginStatusBO)res.getData();
//            photo.setCreateUser(user.getUsername());
//        }
        photo.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
        Integer iresult= service.insertPhotoData(photo);
        return super.result();
    }

    @PostMapping("/photo/list")
    @ApiOperation(value = "试验拍照数据列表")
    public ResultVO<IPage<photoResultEntity>> photopaging(@RequestBody PagingReqDTO<photoDataReqDto> reqDTO) {
        IPage<photoResultEntity> res = service.photopaging(reqDTO);
        List<photoResultEntity> list = res.getRecords();
        return super.result(list);
    }


    /**
     * 新增试验记录模板
     * @param
     * @return
     */
    @PostMapping("/template/add")
    @ApiOperation(value = "实验记录模板新增")
    public ResultVO addTestTemplate(@RequestBody testTempateEntity reqDto) {
        ResultVO res=service.saveTestTemplate(reqDto);
        return res;
    }

    /**
     * 实验记录模板编辑功能
     * @param reqDto
     * @return
     */

    @PostMapping("/template/update")
    @ApiOperation(value = "实验记录模板编辑修改")
    public ResultVO updateTestTemplate(@RequestBody testTempateEntity reqDto) throws InvocationTargetException, IllegalAccessException {
        Integer res=service.updateTestTemplate(reqDto);
        if(res==1){
            return super.result(res);
        }
        return null;
    }

    /**
     * 实验报告模板新增
     * @param reqDto
     * @return
     */
    @PostMapping("/reportTemp/add")
    @ApiOperation(value = "实验报告模板新增")
    public ResultVO addReportTemplate(@RequestBody testReportTemplateEntity reqDto) {
        ResultVO res=service.saveReportTemplate(reqDto);
        return res;
    }


    /**
     * 实验报告编辑修改接口
     * @param reqDto
     * @return
     */
    @PostMapping("/reportTemp/update")
    @ApiOperation(value = "实验报告模板编辑")
    public ResultVO updateReportTemplate(@RequestBody testReportTemplateEntity reqDto) throws InvocationTargetException, IllegalAccessException {
        Integer res=service.updateReportTemplate(reqDto);
        if(res==1){
            return super.result(res);
        }
        return null;
    }

    /**
     * 实验模板删除功能
     * @param id
     * @return
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */

    @GetMapping("/reportTemp/delete")
    @ApiOperation(value = "实验报告模板删除")
    public ResultVO deleteReportTemplate(@RequestParam Integer id)  {
        Integer res=service.deleteReportTemplate(id);
        if(res==1){
            return super.result(res);
        }
        return null;
    }

    @PostMapping("/reportTemplate/paging")
    @ApiOperation(value = "实验报告模板分页查询")
    public ResultVO<IPage<testReportTemplateEntity>> reportPaging(@RequestBody PagingReqDTO<testReportTemplateReqDto> reqDTO) {
        IPage<testReportTemplateEntity> res = service.reportpaging(reqDTO);
        List<testReportTemplateEntity> list = res.getRecords();
        return super.result(res);
    }




    /**
     * 删除实测模板接口功能
     * @param id
     * @return
     */

    @GetMapping("/template/delete")
    @ApiOperation(value = "实验记录模板删除功能")
    public ResultVO deleteTestTemplate(@RequestParam Integer id)  {
        String CC="SSS";
        Integer res=service.deleteTestTemplate(id);
        if(res==1){
            return super.result(res);
        }
        return null;
    }




    /**
     * 根据文档数据更新实测数据到数据库功能
     * @param
     * @return
     */

//    @GetMapping("/docxup/update")
//    @ApiOperation(value = "根据文档数据更新实测数据到数据库功能")
//    public ResultVO deleteTestTemplate1(@RequestParam Integer id){
//        String CC="SSS";
//        Integer res=service.updataTestRecordByDocx(id);
//        return null;
//    }

    @PostMapping("/template/paging")
    @ApiOperation(value = "实验记录模板分页查询")
    public ResultVO<IPage<testTempateEntity>> paging(@RequestBody PagingReqDTO<testTemplateReqDto> reqDTO) {
        IPage<testTempateEntity> res = service.paging(reqDTO);
        List<testTempateEntity> list = res.getRecords();
        return super.result(res);
    }

    /**
     * 将实测记录写入数据库并且将数据写入docx文档里面
     * @param reqdto
     * @return
     */

    @PostMapping("/testdata/add")
    @ApiOperation(value = "实测数据记录上传")
    public ResultVO addTestData(@RequestBody testDataReqDto reqdto) throws Docx4JException, IOException {
        Integer res=service.inserttestRecordData(reqdto);
        return super.result();
    }

    @GetMapping("/testdata/generateDocx")
    @ApiOperation(value = "实测记录数据生成记录报告")
    public ResultVO addTestData(@RequestParam Integer id) throws Docx4JException, IOException {
        //根据实验记录ID获取实验记录数据
        testRecordDataEntity recordData=service.getRecordById(id);
        if(recordData!=null){
           Integer res= service.generateRecordDocx(recordData);
           if(res==0){
               return super.failedResult("生成文档失败，原因是该项目没有配置模板或者模板库不存在模板");
           }
        }

//        Integer res=service.inserttestRecordData(reqdto);
        return super.result();
    }

    @GetMapping("/reportdata/generateDocx")
    @ApiOperation(value = "根据实验报告ID生成实验报告文档")
    public ResultVO addReportData(@RequestParam Integer id) throws Docx4JException, IOException {
        //根据实验记录ID获取实验记录数据
        testReportDataEntity reportData=service.getReportById(id);
        if(reportData!=null){
            Integer res= service.generateReportDocx(reportData);
            if(res==0){
                return super.failedResult("生成文档失败，原因是该项目没有配置模板或者模板库不存在模板");
            }
        }

//        Integer res=service.inserttestRecordData(reqdto);
        return super.result();
    }


    @PostMapping("/testdata/list")
    @ApiOperation(value = "实测详细列表数据")
    public ResultVO<IPage<testRecordDataEntity>> recordpaging(@RequestBody PagingReqDTO<testDataReqDto> reqDTO) {
        IPage<testDataReqDto> res = service.recordpaging(reqDTO);
//        List<testRecordDataEntity> list = res.getRecords();
//        List<testRecordDataEntity> newlist=list.stream().map(item->{
//            JSONObject recordData=JSONObject.parseObject(item.getRecordData());
//            item.setRecordDataJS(recordData);
//            item.setRecordData("");
//            return item;
//        }).collect(Collectors.toList());
//        res.setRecords(newlist);
        return super.result(res);
    }

    @PostMapping("/assign/list")
    @ApiOperation(value = "任务指派记录数据列表")
    public ResultVO assignList(@RequestBody PagingReqDTO<taskAssignReqDto>  reqDTO) {
        IPage<taskAssignEntity> res = service.assignpaging(reqDTO);
        List<taskAssignEntity> list = res.getRecords();
        return super.result(res);
    }




    @GetMapping("/reportData/add")
    @ApiOperation(value = "新增试验报告数据项")
    public ResultVO reportDataAdd(@RequestParam Integer recordDataId,@RequestParam String createUser,@RequestParam String createTime) throws IOException, Docx4JException {
         Integer res= service.generateReportData(recordDataId,createUser,createTime);
         if(res==0){
             return super.failedResult("当前汽车类型以及项目下无匹配报告模板，生成报告数据失败！") ;
         }
        if(res==1){
            return super.result(res) ;
        }
        return super.result();
    }

    @PostMapping("/reportData/list")
    @ApiOperation(value = "实验报告数据分页查询")
    public ResultVO<IPage<testReportDataRes>> reportdataPaging(@RequestBody PagingReqDTO<testReportDataBaseEntity> reqDTO) {
        IPage<testReportDataRes> res = service.reportdatapaging(reqDTO);
//        List<testReportTemplateReqDto> list = res.getRecords();
        return super.result(res);
    }


    @PostMapping("/testdata/update")
    @ApiOperation(value = "实验记录数据编辑修改功能")
    public ResultVO updateTestRecordDtata(@RequestBody testDataReqDto reqDTO) throws InvocationTargetException, IllegalAccessException {
        Integer res= service.updateTestRecordDtata(reqDTO);
        if(res==1){
            return super.result(res) ;
        }
        return super.failedResult("实测数据更新失败") ;
    }

    @GetMapping("/reportTemplate/transform")
    @ApiOperation(value = "实验报告模板由实验记录一键转化功能")
    public ResultVO reportTransform(@RequestParam String veType,@RequestParam String prjNum) throws InvocationTargetException, IllegalAccessException {
        testTempateEntity reportTemp = service.reportTransform(veType,prjNum);
        if(reportTemp.getParamInfo()!=null&&reportTemp.getParamInfo()!=""){
            return super.result(reportTemp) ;
        }
        else{
            return super.failedResult("当前汽车类型以及项目下无匹配的实验记录模板！") ;
        }

    }


    @GetMapping("/testdata/TestDataToDocx")
    @ApiOperation(value = "实验记录数据转移到docx文档里面")
    public ResultVO TestDataToDocx(@RequestParam Integer id) throws Docx4JException {
        Integer res=service.TestDataToDocx(id);
        return super.result();
    }



    @GetMapping("/testdata/showdocx")
    @ApiOperation(value = "实验记录数据文档展示")
    public void transfer(@RequestParam String docxFilename,HttpServletResponse res) throws Exception {
        res.setHeader("Content-Type", "application/docx");
        if(docxFilename!=null&&docxFilename!=""){
            String path= recordDocxPath + docxFilename;
            File f = new File(path);//path 文件的相对路径
            ServletOutputStream outputStream = res.getOutputStream();
            outputStream.write(FileUtil.readBytes(f));//hutool 工具类 FileUtil
            //强制将缓存区的数据进行输出
            outputStream.flush();
            //关流
            outputStream.close();
        }
    }


    /*@PostMapping("/testdata/testSaveDOcx")
    @ApiOperation(value = "实验记录数据文档保存")
    public String testSaveDOcx(HttpServletRequest request, HttpServletResponse response) throws IOException {
        PrintWriter writer = response.getWriter();
        Scanner scanner = new Scanner(request.getInputStream()).useDelimiter("\\A");
        String body = scanner.hasNext() ? scanner.next() : "";
        try {
            JSONObject jsonObj = (JSONObject) new JSONParser().parse(body);
            System.out.println(jsonObj);

            if((long) jsonObj.get("status") == 2) {
                String downloadUri = (String) jsonObj.get("url");
                URL url = new URL(downloadUri);
                java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
                InputStream stream = connection.getInputStream();
                String pathForSave = "D:/";
                File savedFile = new File(pathForSave);
                try (FileOutputStream out = new FileOutputStream(savedFile)) {
                    int read;
                    final byte[] bytes = new byte[1024];
                    while ((read = stream.read(bytes)) != -1) {
                        out.write(bytes, 0, read);
                    }
                    out.flush();
                }
                connection.disconnect();
            }
            writer.write("{\"error\":0}");
            return "{\"error\":0}";
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return "{\"error\":0}";
    }*/


    @RequestMapping(value = "/docx/save",
            method = RequestMethod.POST,
            produces = "application/json;charset=UTF-8")
    @ResponseBody
    public void saveWord(HttpServletRequest request, HttpServletResponse response) {
        try {
            PrintWriter writer = response.getWriter();
            String body = "";

            try
            {
                Scanner scanner = new Scanner(request.getInputStream());
                scanner.useDelimiter("\\A");
                body = scanner.hasNext() ? scanner.next() : "";
                scanner.close();
            }
            catch (Exception ex)
            {
                writer.write("get request.getInputStream error:" + ex.getMessage());
                return;
            }

            if (body.isEmpty())
            {
                writer.write("empty request.getInputStream");
                return;
            }

            JSONObject jsonObj = JSON.parseObject(body);

            int status = (Integer) jsonObj.get("status");

            int saved = 0;
            if(status == 2 || status == 3) //MustSave, Corrupted
            {
                String downloadUri = (String) jsonObj.get("url");

                try
                {
                    URL url = new URL(downloadUri);
                    java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
                    InputStream stream = connection.getInputStream();

                    if (stream == null)
                    {
                        throw new Exception("Stream is null");
                    }

                    String path = request.getParameter("path");

                    Integer id=Integer.parseInt(request.getParameter("id"));
                    testRecordDataEntity et=service.getRecordById(id);
                    String fileName=et.getDocxFileName();
//                    String pathForSave = "D:/test111.docx";
                    String pathForSave =recordDocxPath + fileName;
                    System.out.println(pathForSave);
                    File savedFile = new File(pathForSave);
                    try (FileOutputStream out = new FileOutputStream(savedFile))
                    {
                        int read;
                        final byte[] bytes = new byte[1024];
                        while ((read = stream.read(bytes)) != -1)
                        {
                            out.write(bytes, 0, read);
                        }

                        out.flush();
                    }

                    connection.disconnect();
                    String docxFileName=request.getParameter("docxFileName");
                    //获取保存进入数据库的实验记录数据，通过数据ID和文档书签信息对数据库实测记录数据进行更新
                    Integer res=service.updataTestRecordByDocx(et);
                }
                catch (Exception ex)
                {
                    saved = 1;
                    ex.printStackTrace();
                }

            }writer.write("{\"error\":" + saved + "}");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


}
